﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Generator.DynamicAttributeBlockCodeGenerator
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using Microsoft.Internal.Web.Utils;
using System.Globalization;
using System.Linq;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Text;

namespace System.Web.Razor.Generator
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Represents the dynamic attributes of the block code generator.</summary>
  public class DynamicAttributeBlockCodeGenerator : BlockCodeGenerator
  {
    private const string ValueWriterName = "__razor_attribute_value_writer";
    private string _oldTargetWriter;
    private bool _isExpression;
    private ExpressionRenderingMode _oldRenderingMode;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instances of the <see cref="T:System.Web.Razor.Generator.DynamicAttributeBlockCodeGenerator" /> class.</summary>
    /// <param name="prefix">The prefix.</param>
    /// <param name="offset">The offset values.</param>
    /// <param name="line">The line values.</param>
    /// <param name="col">The col.</param>
    public DynamicAttributeBlockCodeGenerator(
      LocationTagged<string> prefix,
      int offset,
      int line,
      int col)
      : this(prefix, new SourceLocation(offset, line, col))
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instances of the <see cref="T:System.Web.Razor.Generator.DynamicAttributeBlockCodeGenerator" /> class.</summary>
    /// <param name="prefix">The string prefix.</param>
    /// <param name="valueStart">The value start.</param>
    public DynamicAttributeBlockCodeGenerator(
      LocationTagged<string> prefix,
      SourceLocation valueStart)
    {
      this.Prefix = prefix;
      this.ValueStart = valueStart;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the namespace prefix of the code generator.</summary>
    /// <returns>The namespace prefix of the code generator.</returns>
    public LocationTagged<string> Prefix { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the value start for the dynamic attribute block code generator.</summary>
    /// <returns>The value start for the dynamic attribute block code generator.</returns>
    public SourceLocation ValueStart { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Generates code to start the block using the specified parameters.</summary>
    /// <param name="target">The target block.</param>
    /// <param name="context">The code generator context.</param>
    public override void GenerateStartBlockCode(Block target, CodeGeneratorContext context)
    {
      if (context.Host.DesignTimeMode)
        return;
      Block block = target.Children.Where<SyntaxTreeNode>((Func<SyntaxTreeNode, bool>) (n => n.IsBlock)).Cast<Block>().FirstOrDefault<Block>();
      string fragment;
      if (block != null && block.Type == BlockType.Expression)
      {
        this._isExpression = true;
        fragment = context.BuildCodeString((Action<CodeWriter>) (cw =>
        {
          cw.WriteParameterSeparator();
          cw.WriteStartMethodInvoke("Tuple.Create");
          cw.WriteLocationTaggedString(this.Prefix);
          cw.WriteParameterSeparator();
          cw.WriteStartMethodInvoke("Tuple.Create", "System.Object", "System.Int32");
        }));
        this._oldRenderingMode = context.ExpressionRenderingMode;
        context.ExpressionRenderingMode = ExpressionRenderingMode.InjectCode;
      }
      else
        fragment = context.BuildCodeString((Action<CodeWriter>) (cw =>
        {
          cw.WriteParameterSeparator();
          cw.WriteStartMethodInvoke("Tuple.Create");
          cw.WriteLocationTaggedString(this.Prefix);
          cw.WriteParameterSeparator();
          cw.WriteStartMethodInvoke("Tuple.Create", "System.Object", "System.Int32");
          cw.WriteStartConstructor(context.Host.GeneratedClassContext.TemplateTypeName);
          cw.WriteStartLambdaDelegate("__razor_attribute_value_writer");
        }));
      context.MarkEndOfGeneratedCode();
      context.BufferStatementFragment(fragment);
      this._oldTargetWriter = context.TargetWriterName;
      context.TargetWriterName = "__razor_attribute_value_writer";
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Generates code to end the block using the specified parameters.</summary>
    /// <param name="target">The target block.</param>
    /// <param name="context">The code generator context.</param>
    public override void GenerateEndBlockCode(Block target, CodeGeneratorContext context)
    {
      if (context.Host.DesignTimeMode)
        return;
      string generatedCode;
      if (this._isExpression)
      {
        generatedCode = context.BuildCodeString((Action<CodeWriter>) (cw =>
        {
          cw.WriteParameterSeparator();
          cw.WriteSnippet(this.ValueStart.AbsoluteIndex.ToString((IFormatProvider) CultureInfo.CurrentCulture));
          cw.WriteEndMethodInvoke();
          cw.WriteParameterSeparator();
          cw.WriteBooleanLiteral(false);
          cw.WriteEndMethodInvoke();
          cw.WriteLineContinuation();
        }));
        context.ExpressionRenderingMode = this._oldRenderingMode;
      }
      else
        generatedCode = context.BuildCodeString((Action<CodeWriter>) (cw =>
        {
          cw.WriteEndLambdaDelegate();
          cw.WriteEndConstructor();
          cw.WriteParameterSeparator();
          cw.WriteSnippet(this.ValueStart.AbsoluteIndex.ToString((IFormatProvider) CultureInfo.CurrentCulture));
          cw.WriteEndMethodInvoke();
          cw.WriteParameterSeparator();
          cw.WriteBooleanLiteral(false);
          cw.WriteEndMethodInvoke();
          cw.WriteLineContinuation();
        }));
      context.AddStatement(generatedCode);
      context.TargetWriterName = this._oldTargetWriter;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Returns a string that represents the current object.</summary>
    /// <returns>A string that represents the current object.</returns>
    public override string ToString() => string.Format((IFormatProvider) CultureInfo.CurrentCulture, "DynAttr:{0:F}", (object) this.Prefix);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the specified object is equal to the current object.</summary>
    /// <returns>true if the specified object is equal to the current object; otherwise, false.</returns>
    /// <param name="obj">The object to compare with the current object.</param>
    public override bool Equals(object obj) => obj is DynamicAttributeBlockCodeGenerator blockCodeGenerator && object.Equals((object) blockCodeGenerator.Prefix, (object) this.Prefix);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Returns the hash code for this instance.</summary>
    /// <returns>The hash code for this instance.</returns>
    public override int GetHashCode() => HashCodeCombiner.Start().Add((object) this.Prefix).CombinedHash;
  }
}
